use image::DynamicImage;
use std::sync::{Arc, Mutex};
use tauri::Manager;

use crate::clipboard::copy_image_to_clipboard;
#[cfg(target_os = "macos")]
use crate::macos_window::{set_window_level_above_menu, set_window_transparent};

/// 截图缓存结构
pub struct ScreenshotCache {
    pub image: Mutex<Option<DynamicImage>>,
    pub screen_x: Mutex<i32>,
    pub screen_y: Mutex<i32>,
}

/// 截图状态管理（防止重复触发）
pub struct ScreenshotState {
    pub is_capturing: Mutex<bool>,
}

impl ScreenshotCache {
    pub fn new() -> Self {
        Self {
            image: Mutex::new(None),
            screen_x: Mutex::new(0),
            screen_y: Mutex::new(0),
        }
    }
}

impl ScreenshotState {
    pub fn new() -> Self {
        Self {
            is_capturing: Mutex::new(false),
        }
    }
}

/// 预先截取屏幕并缓存
pub async fn capture_and_cache_screen(app: &tauri::AppHandle) -> Result<(), String> {
    // 获取所有屏幕
    let screens = screenshots::Screen::all().map_err(|e| format!("无法获取屏幕列表: {}", e))?;

    if screens.is_empty() {
        return Err("未找到可用的屏幕".to_string());
    }

    // 获取当前鼠标位置
    let mouse_pos = app
        .cursor_position()
        .map_err(|e| format!("获取鼠标位置失败: {}", e))?;

    // 查找鼠标所在的屏幕
    let screen = screens
        .iter()
        .find(|s| {
            let info = &s.display_info;
            mouse_pos.x >= info.x as f64
                && mouse_pos.x < (info.x + info.width as i32) as f64
                && mouse_pos.y >= info.y as f64
                && mouse_pos.y < (info.y + info.height as i32) as f64
        })
        .unwrap_or(&screens[0]); // 如果找不到，回退到主屏幕

    let screen_x = screen.display_info.x;
    let screen_y = screen.display_info.y;

    let image = screen.capture().map_err(|e| format!("截图失败: {}", e))?;

    // 转换为 DynamicImage
    let temp_file =
        std::env::temp_dir().join(format!("screenshot_cache_{}.png", std::process::id()));
    let png_data = image
        .to_png(None)
        .map_err(|e| format!("转换为 PNG 失败: {}", e))?;
    std::fs::write(&temp_file, png_data).map_err(|e| format!("保存临时图像失败: {}", e))?;

    let dynamic_image = image::open(&temp_file).map_err(|e| format!("读取图像失败: {}", e))?;

    // 清理临时文件
    let _ = std::fs::remove_file(&temp_file);

    // 缓存到全局状态
    let cache = app.state::<ScreenshotCache>();
    *cache.image.lock().unwrap() = Some(dynamic_image);
    *cache.screen_x.lock().unwrap() = screen_x;
    *cache.screen_y.lock().unwrap() = screen_y;

    Ok(())
}

/// 启动屏幕截图遮罩（为所有屏幕创建全屏透明窗口）
#[tauri::command]
pub async fn start_screenshot_overlay(app: tauri::AppHandle) -> Result<(), String> {
    // 权限校验：仅在权限通过后才创建遮罩窗口
    // TODO: 暂时先不校验了
    // #[cfg(target_os = "macos")]
    // {
    //     if let Err(e) = ensure_screen_capture_permission() {
    //         return Err(e);
    //     }
    // }
    // 防抖：检查是否正在截图
    let state = app.state::<ScreenshotState>();
    {
        let mut is_capturing = state.is_capturing.lock().unwrap();
        if *is_capturing {
            eprintln!("截图正在进行中，忽略重复请求");
            return Ok(());
        }
        *is_capturing = true;
    }

    // 隐藏当前主窗口（如果存在）
    if let Some(main_window) = app.get_webview_window("main") {
        let _ = main_window.hide();
    }

    // 关闭所有可能已存在的遮罩窗口
    if let Some(existing_overlay) = app.get_webview_window("screenshot_overlay") {
        let _ = existing_overlay.close();
    }
    for i in 0..10 {
        let window_label = format!("screenshot_overlay_{}", i);
        if let Some(existing_overlay) = app.get_webview_window(&window_label) {
            let _ = existing_overlay.close();
        }
    }

    // 获取当前鼠标位置
    let mouse_pos = app
        .cursor_position()
        .map_err(|e| format!("获取鼠标位置失败: {}", e))?;

    // 获取所有显示器（仅在触发时获取一次）
    let monitors = app
        .available_monitors()
        .map_err(|e| format!("获取显示器列表失败: {}", e))?;
    // 查找鼠标所在的显示器索引（用于后续截图）
    let primary_monitor_index = monitors
        .iter()
        .position(|m| {
            let position = m.position();
            let size = m.size();
            mouse_pos.x >= position.x as f64
                && mouse_pos.x < (position.x + size.width as i32) as f64
                && mouse_pos.y >= position.y as f64
                && mouse_pos.y < (position.y + size.height as i32) as f64
        })
        .unwrap_or(0);

    // 固化显示器信息以便后续跨屏焦点切换时使用（避免频繁 available_monitors）
    #[derive(Clone, Copy)]
    struct MonitorInfo {
        x: i32,
        y: i32,
        width: i32,
        height: i32,
    }
    let monitor_infos = Arc::new(Mutex::new(
        monitors
            .iter()
            .map(|m| {
                let pos = m.position();
                let size = m.size();
                MonitorInfo {
                    x: pos.x,
                    y: pos.y,
                    width: size.width as i32,
                    height: size.height as i32,
                }
            })
            .collect::<Vec<_>>(),
    ));

    // 为每个显示器创建遮罩窗口
    let mut created_windows = Vec::new();

    for (index, monitor) in monitors.iter().enumerate() {
        let monitor_position = monitor.position();
        let monitor_size = monitor.size();
        let scale_factor = monitor.scale_factor();
        let window_label = format!("screenshot_overlay_{}", index);
        let is_primary = index == primary_monitor_index;

        eprintln!(
            "\n📺 显示器 #{} {}:",
            index,
            if is_primary { "(鼠标所在)" } else { "" }
        );
        eprintln!(
            "  - 名称: {}",
            monitor
                .name()
                .map(|s| s.to_string())
                .unwrap_or("未知".to_string())
        );
        eprintln!("  - 位置: ({}, {})", monitor_position.x, monitor_position.y);
        eprintln!(
            "  - 尺寸: {} x {} (物理像素)",
            monitor_size.width, monitor_size.height
        );
        eprintln!("  - 缩放: {}", scale_factor);

        let overlay_window = tauri::WebviewWindowBuilder::new(
            &app,
            &window_label,
            tauri::WebviewUrl::App("/#/screenShotOverlay".into()),
        )
        .title(&format!("截屏遮罩 {}", index))
        .inner_size(
            monitor_size.width as f64 / scale_factor,
            monitor_size.height as f64 / scale_factor,
        )
        .position(monitor_position.x as f64, monitor_position.y as f64)
        .decorations(false)
        .transparent(true)
        .always_on_top(true)
        .skip_taskbar(true)
        .resizable(false)
        .fullscreen(false)
        .visible(false)
        .build()
        .map_err(|e| format!("创建遮罩窗口失败: {}", e))?;

        #[cfg(target_os = "macos")]
        {
            use cocoa::appkit::NSWindow;
            use cocoa::base::id;
            let ns_window = overlay_window.ns_window().unwrap() as id;
            unsafe {
                ns_window.setAcceptsMouseMovedEvents_(cocoa::base::YES);
            }
        }
        created_windows.push(overlay_window);
    }

    // 显示所有遮罩窗口
    for (index, window) in created_windows.iter().enumerate() {
        window
            .show()
            .map_err(|e| format!("显示遮罩窗口 {} 失败: {}", index, e))?;
    }

    // 初始将焦点设置到鼠标所在屏幕的遮罩窗口
    if let Some(primary_window) = created_windows.get(primary_monitor_index) {
        let _ = primary_window.set_focus();
    }

    // 在 macOS 上设置窗口层级和透明背景
    #[cfg(target_os = "macos")]
    {
        tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;

        for (index, window) in created_windows.iter().enumerate() {
            let window_handle = window.clone();
            let idx = index;
            app.run_on_main_thread(move || {
                if let Err(e) = set_window_level_above_menu(&window_handle) {
                    eprintln!("❌ 遮罩 {} 设置窗口层级失败: {}", idx, e);
                }
                if let Err(e) = set_window_transparent(&window_handle) {
                    eprintln!("❌ 遮罩 {} 设置窗口透明失败: {}", idx, e);
                }
            })
            .map_err(|e| format!("无法在主线程执行窗口操作: {}", e))?;
        }
        eprintln!("✅ 所有遮罩窗口层级和透明度已设置");
    }

    // 在后台异步截取屏幕并缓存
    let app_clone = app.clone();
    tokio::spawn(async move {
        eprintln!("后台截取屏幕...");
        match capture_and_cache_screen(&app_clone).await {
            Ok(_) => eprintln!("屏幕截图已缓存"),
            Err(e) => eprintln!("警告: 预先截图失败: {}", e),
        }
    });

    // 新增：后台任务，按鼠标所在屏幕动态切换焦点到对应遮罩窗口
    let app_clone_for_focus = app.clone();
    let monitor_infos_for_focus = monitor_infos.clone();
    tokio::spawn(async move {
        let mut last_monitor_index = primary_monitor_index;
        loop {
            tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;

            let is_capturing = {
                let state = app_clone_for_focus.state::<ScreenshotState>();
                let guard = state.is_capturing.lock().unwrap();
                *guard
            };
            if !is_capturing {
                break;
            }

            let mouse_pos = match app_clone_for_focus.cursor_position() {
                Ok(pos) => pos,
                Err(_) => continue,
            };

            let infos = monitor_infos_for_focus.lock().unwrap();
            let current_index_opt = infos
                .iter()
                .position(|info| is_point_in_monitor(mouse_pos.x, mouse_pos.y, info));

            let current_index = match current_index_opt {
                Some(idx) => idx,
                None => {
                    let mut nearest_idx = last_monitor_index;
                    let mut nearest_d2 = f64::INFINITY;
                    for (i, info) in infos.iter().enumerate() {
                        let left = info.x as f64;
                        let right = (info.x + info.width - 1) as f64;
                        let top = info.y as f64;
                        let bottom = (info.y + info.height - 1) as f64;
                        let dx = if mouse_pos.x < left {
                            left - mouse_pos.x
                        } else if mouse_pos.x > right {
                            mouse_pos.x - right
                        } else {
                            0.0
                        };
                        let dy = if mouse_pos.y < top {
                            top - mouse_pos.y
                        } else if mouse_pos.y > bottom {
                            mouse_pos.y - bottom
                        } else {
                            0.0
                        };
                        let d2 = dx * dx + dy * dy;
                        if d2 < nearest_d2 {
                            nearest_d2 = d2;
                            nearest_idx = i;
                        }
                    }
                    nearest_idx
                }
            };

            if current_index != last_monitor_index {
                let label = format!("screenshot_overlay_{}", current_index);
                if let Some(window) = app_clone_for_focus.get_webview_window(&label) {
                    if window.set_focus().is_ok() {
                        last_monitor_index = current_index;
                    }
                }
            }
        }
    });

    // 辅助函数：判断点是否在显示器范围内
    fn is_point_in_monitor(x: f64, y: f64, info: &MonitorInfo) -> bool {
        let left = info.x as f64;
        let right = (info.x + info.width) as f64;
        let top = info.y as f64;
        let bottom = (info.y + info.height) as f64;

        x >= left && x < right && y >= top && y < bottom
    }

    Ok(())
}

/// 关闭所有遮罩窗口
#[tauri::command]
pub async fn close_overlay_window(app: tauri::AppHandle) -> Result<(), String> {
    // 重置截图状态
    let state = app.state::<ScreenshotState>();
    {
        let mut is_capturing = state.is_capturing.lock().unwrap();
        *is_capturing = false;
    }

    // 关闭遮罩窗口
    let mut closed_count = 0;
    if let Some(overlay) = app.get_webview_window("screenshot_overlay") {
        overlay.close().map_err(|e| e.to_string())?;
        closed_count += 1;
    }
    for i in 0..10 {
        let window_label = format!("screenshot_overlay_{}", i);
        if let Some(overlay) = app.get_webview_window(&window_label) {
            overlay.close().map_err(|e| e.to_string())?;
            closed_count += 1;
        }
    }

    Ok(())
}

/// 关闭除当前窗口外的其他遮罩窗口
#[tauri::command]
pub async fn close_other_overlays(window: tauri::WebviewWindow) -> Result<(), String> {
    let current_label = window.label();
    let app = window.app_handle();

    // 关闭其他遮罩窗口
    let mut closed_count = 0;
    for i in 0..10 {
        let window_label = format!("screenshot_overlay_{}", i);
        if window_label != current_label {
            if let Some(overlay) = app.get_webview_window(&window_label) {
                overlay.close().map_err(|e| e.to_string())?;
                closed_count += 1;
            }
        }
    }

    eprintln!(
        "✅ 已关闭 {} 个其他遮罩窗口，保留当前窗口 {}",
        closed_count, current_label
    );

    Ok(())
}

/// 从缓存中快速裁剪并保存截图
#[tauri::command]
pub async fn capture_from_cache(
    app: tauri::AppHandle,
    x: i32,
    y: i32,
    width: u32,
    height: u32,
) -> Result<String, String> {
    use std::time::{SystemTime, UNIX_EPOCH};

    eprintln!(
        "从缓存裁剪截图: x={}, y={}, width={}, height={}",
        x, y, width, height
    );

    // 从缓存获取图像
    let cache = app.state::<ScreenshotCache>();
    let image_opt = cache.image.lock().unwrap();
    let cached_image = image_opt.as_ref().ok_or("截图缓存为空，请重新截图")?;

    let screen_x = *cache.screen_x.lock().unwrap();
    let screen_y = *cache.screen_y.lock().unwrap();

    // 计算相对坐标
    let relative_x = x - screen_x;
    let relative_y = y - screen_y;

    eprintln!(
        "屏幕偏移: ({}, {}), 相对坐标: ({}, {})",
        screen_x, screen_y, relative_x, relative_y
    );

    // 验证坐标
    if relative_x < 0
        || relative_y < 0
        || (relative_x + width as i32) > cached_image.width() as i32
        || (relative_y + height as i32) > cached_image.height() as i32
    {
        return Err(format!(
            "截图区域超出屏幕范围: 图像尺寸 {}x{}, 请求区域 {}x{} at ({}, {})",
            cached_image.width(),
            cached_image.height(),
            width,
            height,
            x,
            y
        ));
    }

    // 裁剪图像
    let rgba_img = cached_image.to_rgba8();
    use image::imageops;
    let cropped_img = imageops::crop_imm(
        &rgba_img,
        relative_x as u32,
        relative_y as u32,
        width,
        height,
    );
    let final_img = cropped_img.to_image();

    // 生成文件名
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();
    let filename = format!("screenshot_{}.png", timestamp);

    // 获取桌面目录
    let desktop_dir = app
        .path()
        .desktop_dir()
        .map_err(|e| format!("无法获取桌面目录: {}", e))?;

    let file_path = desktop_dir.join(&filename);

    // 保存图像
    final_img
        .save(&file_path)
        .map_err(|e| format!("保存截图失败: {}", e))?;

    let file_path_str = file_path.to_str().ok_or("文件路径无效")?.to_string();

    // 复制到剪贴板（macOS）
    #[cfg(target_os = "macos")]
    {
        if let Err(e) = copy_image_to_clipboard(&file_path_str) {
            eprintln!("复制到剪贴板失败: {}", e);
        }
    }

    Ok(file_path_str)
}

/// 从缓存中快速裁剪并复制到剪贴板（不保存文件）
#[tauri::command]
pub async fn copy_from_cache(
    app: tauri::AppHandle,
    x: i32,
    y: i32,
    width: u32,
    height: u32,
) -> Result<(), String> {
    // 从缓存获取图像
    let cache = app.state::<ScreenshotCache>();
    let image_opt = cache.image.lock().unwrap();
    let cached_image = image_opt.as_ref().ok_or("截图缓存为空，请重新截图")?;

    let screen_x = *cache.screen_x.lock().unwrap();
    let screen_y = *cache.screen_y.lock().unwrap();

    // 计算相对坐标
    let relative_x = x - screen_x;
    let relative_y = y - screen_y;

    // 验证坐标
    if relative_x < 0
        || relative_y < 0
        || (relative_x + width as i32) > cached_image.width() as i32
        || (relative_y + height as i32) > cached_image.height() as i32
    {
        return Err("截图区域超出屏幕范围".to_string());
    }

    // 裁剪图像
    let rgba_img = cached_image.to_rgba8();
    use image::imageops;
    let cropped_img = imageops::crop_imm(
        &rgba_img,
        relative_x as u32,
        relative_y as u32,
        width,
        height,
    );
    let final_img = cropped_img.to_image();

    // 保存到临时文件用于复制到剪贴板
    let temp_file =
        std::env::temp_dir().join(format!("screenshot_clipboard_{}.png", std::process::id()));
    final_img
        .save(&temp_file)
        .map_err(|e| format!("保存临时图像失败: {}", e))?;

    let temp_path_str = temp_file.to_str().ok_or("文件路径无效")?;

    // 复制到剪贴板
    #[cfg(target_os = "macos")]
    {
        copy_image_to_clipboard(temp_path_str)?;
    }

    #[cfg(not(target_os = "macos"))]
    {
        return Err("当前平台暂不支持复制到剪贴板".to_string());
    }

    // 清理临时文件
    let _ = std::fs::remove_file(&temp_file);

    Ok(())
}

/// 将选定区域贴图到桌面
#[tauri::command]
pub async fn pin_selected_area(
    app: tauri::AppHandle,
    x: i32,
    y: i32,
    width: u32,
    height: u32,
    logical_x: Option<f64>,
    logical_y: Option<f64>,
    logical_width: Option<f64>,
    logical_height: Option<f64>,
) -> Result<(), String> {
    use std::time::{SystemTime, UNIX_EPOCH};

    // 从缓存获取图像
    let cache = app.state::<ScreenshotCache>();
    let image_opt = cache.image.lock().unwrap();
    let cached_image = image_opt.as_ref().ok_or("截图缓存为空，请重新截图")?;

    let screen_x = *cache.screen_x.lock().unwrap();
    let screen_y = *cache.screen_y.lock().unwrap();

    // 计算相对坐标
    let relative_x = x - screen_x;
    let relative_y = y - screen_y;

    // 验证坐标
    if relative_x < 0
        || relative_y < 0
        || (relative_x + width as i32) > cached_image.width() as i32
        || (relative_y + height as i32) > cached_image.height() as i32
    {
        eprintln!("错误: 截图区域超出屏幕范围");
        return Err("截图区域超出屏幕范围".to_string());
    }

    // 裁剪图像
    let rgba_img = cached_image.to_rgba8();
    use image::imageops;
    let cropped_img = imageops::crop_imm(
        &rgba_img,
        relative_x as u32,
        relative_y as u32,
        width,
        height,
    );
    let final_img = cropped_img.to_image();

    // 保存到临时文件
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_millis();
    let temp_file = std::env::temp_dir().join(format!("pin_image_{}.png", timestamp));

    final_img.save(&temp_file).map_err(|e| {
        eprintln!("保存临时图像失败: {}", e);
        format!("保存临时图像失败: {}", e)
    })?;

    let file_path_str = temp_file.to_str().ok_or("文件路径无效")?.to_string();

    // 创建贴图窗口
    let label = format!("pin_window_{}", timestamp);

    // 使用 base64 编码路径
    use base64::engine::general_purpose;
    use base64::Engine;
    let encoded_path = general_purpose::STANDARD.encode(file_path_str.as_bytes());

    let url = format!("/#/pin-window?path={}", encoded_path);

    // 使用逻辑坐标设置窗口位置和大小
    let window_x = logical_x.unwrap_or(x as f64);
    let window_y = logical_y.unwrap_or(y as f64);
    let window_width = logical_width.unwrap_or(width as f64);
    let window_height = logical_height.unwrap_or(height as f64);

    let window = tauri::WebviewWindowBuilder::new(&app, label, tauri::WebviewUrl::App(url.into()))
        .title("贴图")
        .inner_size(window_width, window_height)
        .position(window_x, window_y)
        .decorations(false)
        .transparent(true)
        .always_on_top(true)
        .skip_taskbar(true)
        .resizable(true)
        .build()
        .map_err(|e| {
            eprintln!("创建窗口失败: {}", e);
            e.to_string()
        })?;

    window.show().map_err(|e| {
        eprintln!("显示窗口失败: {}", e);
        e.to_string()
    })?;

    Ok(())
}

/// 截图选定的区域（保留用于向后兼容）
#[tauri::command]
pub async fn capture_selected_area(
    app: tauri::AppHandle,
    x: i32,
    y: i32,
    width: u32,
    height: u32,
) -> Result<String, String> {
    use std::time::{SystemTime, UNIX_EPOCH};

    // 捕获整个屏幕
    let screens = screenshots::Screen::all()
        .map_err(|e| format!("无法获取屏幕列表: {}。请确保应用有屏幕录制权限。", e))?;

    if screens.is_empty() {
        return Err("未找到可用的屏幕".to_string());
    }

    // 查找包含指定坐标的屏幕
    let screen = screens
        .iter()
        .find(|s| {
            let display = s.display_info;
            x >= display.x
                && y >= display.y
                && x < display.x + display.width as i32
                && y < display.y + display.height as i32
        })
        .unwrap_or(&screens[0]);

    let image = screen
        .capture()
        .map_err(|e| format!("截图失败: {}。请确保应用有屏幕录制权限。", e))?;

    let img_width = image.width();
    let img_height = image.height();

    // 计算相对坐标
    let screen_x = screen.display_info.x;
    let screen_y = screen.display_info.y;
    let relative_x = x - screen_x;
    let relative_y = y - screen_y;

    // 验证坐标
    if relative_x < 0
        || relative_y < 0
        || (relative_x + width as i32) > img_width as i32
        || (relative_y + height as i32) > img_height as i32
    {
        return Err(format!(
            "截图区域超出屏幕范围: 屏幕尺寸 {}x{}, 屏幕偏移 ({}, {}), 请求区域 {}x{} at ({}, {})",
            img_width, img_height, screen_x, screen_y, width, height, x, y
        ));
    }

    // 保存到临时文件
    let temp_file =
        std::env::temp_dir().join(format!("screenshot_temp_{}.png", std::process::id()));

    let png_data = image
        .to_png(None)
        .map_err(|e| format!("转换为 PNG 失败: {}", e))?;

    std::fs::write(&temp_file, png_data).map_err(|e| format!("保存临时图像失败: {}", e))?;

    // 裁剪图像
    let full_img = image::open(&temp_file).map_err(|e| format!("读取图像失败: {}", e))?;

    let rgba_img = full_img.to_rgba8();

    use image::imageops;
    let cropped_img = imageops::crop_imm(
        &rgba_img,
        relative_x as u32,
        relative_y as u32,
        width,
        height,
    );
    let final_img = cropped_img.to_image();

    // 清理临时文件
    let _ = std::fs::remove_file(&temp_file);

    // 生成文件名
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();

    let filename = format!("screenshot_{}.png", timestamp);

    // 获取桌面目录
    let desktop_dir = app
        .path()
        .desktop_dir()
        .map_err(|e| format!("无法获取桌面目录: {}", e))?;

    let file_path = desktop_dir.join(&filename);

    // 保存图像
    final_img
        .save(&file_path)
        .map_err(|e| format!("保存截图失败: {}", e))?;

    let file_path_str = file_path.to_str().ok_or("文件路径无效")?.to_string();

    // 复制到剪贴板（macOS）
    #[cfg(target_os = "macos")]
    {
        copy_image_to_clipboard(&file_path_str)
            .unwrap_or_else(|e| eprintln!("复制到剪贴板失败: {}", e));
    }

    Ok(file_path_str)
}

/// 只复制截图到剪贴板，不保存文件
#[tauri::command]
pub async fn copy_selected_area_to_clipboard(
    _app: tauri::AppHandle,
    x: i32,
    y: i32,
    width: u32,
    height: u32,
) -> Result<(), String> {
    // 捕获整个屏幕
    let screens = screenshots::Screen::all()
        .map_err(|e| format!("无法获取屏幕列表: {}。请确保应用有屏幕录制权限。", e))?;

    if screens.is_empty() {
        return Err("未找到可用的屏幕".to_string());
    }

    // 查找包含指定坐标的屏幕
    let screen = screens
        .iter()
        .find(|s| {
            let display = s.display_info;
            x >= display.x
                && y >= display.y
                && x < display.x + display.width as i32
                && y < display.y + display.height as i32
        })
        .unwrap_or(&screens[0]);

    let image = screen
        .capture()
        .map_err(|e| format!("截图失败: {}。请确保应用有屏幕录制权限。", e))?;

    // 计算相对坐标
    let screen_x = screen.display_info.x;
    let screen_y = screen.display_info.y;
    let relative_x = x - screen_x;
    let relative_y = y - screen_y;

    // 验证坐标
    if relative_x < 0
        || relative_y < 0
        || (relative_x + width as i32) > image.width() as i32
        || (relative_y + height as i32) > image.height() as i32
    {
        return Err("截图区域超出屏幕范围".to_string());
    }

    // 保存到临时文件
    let temp_file =
        std::env::temp_dir().join(format!("screenshot_temp_{}.png", std::process::id()));

    let png_data = image
        .to_png(None)
        .map_err(|e| format!("转换为 PNG 失败: {}", e))?;

    std::fs::write(&temp_file, png_data).map_err(|e| format!("保存临时图像失败: {}", e))?;

    // 裁剪图像
    let full_img = image::open(&temp_file).map_err(|e| format!("读取图像失败: {}", e))?;

    let rgba_img = full_img.to_rgba8();

    use image::imageops;
    let cropped_img = imageops::crop_imm(
        &rgba_img,
        relative_x as u32,
        relative_y as u32,
        width,
        height,
    );
    let final_img = cropped_img.to_image();

    // 保存裁剪后的图像到临时文件
    let cropped_temp_file =
        std::env::temp_dir().join(format!("screenshot_cropped_{}.png", std::process::id()));
    final_img
        .save(&cropped_temp_file)
        .map_err(|e| format!("保存裁剪图像失败: {}", e))?;

    let cropped_path_str = cropped_temp_file.to_str().ok_or("文件路径无效")?;

    // 复制到剪贴板
    #[cfg(target_os = "macos")]
    {
        copy_image_to_clipboard(cropped_path_str)?;
    }

    #[cfg(not(target_os = "macos"))]
    {
        return Err("当前平台暂不支持复制到剪贴板".to_string());
    }

    // 清理临时文件
    let _ = std::fs::remove_file(&temp_file);
    let _ = std::fs::remove_file(&cropped_temp_file);

    Ok(())
}
#[cfg(target_os = "macos")]
#[link(name = "CoreGraphics", kind = "framework")]
extern "C" {
    fn CGPreflightScreenCaptureAccess() -> bool;
    fn CGRequestScreenCaptureAccess() -> bool;
}

#[cfg(target_os = "macos")]
fn ensure_screen_capture_permission() -> Result<(), String> {
    unsafe {
        eprintln!("正在检查屏幕录制权限...");
        let preflight = CGPreflightScreenCaptureAccess();
        eprintln!("权限预检结果: {}", preflight);
        if preflight {
            return Ok(());
        }

        eprintln!("尝试请求屏幕录制权限...");
        let granted = CGRequestScreenCaptureAccess();
        eprintln!("权限请求返回: {}", granted);
        if granted {
            return Ok(());
        }

        // 打开系统设置的屏幕录制隐私页面，便于用户手动授权
        let _ = std::process::Command::new("open")
            .arg("x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture")
            .status();
        Err("屏幕录制权限未授予，请在系统设置中启用后重试".to_string())
    }
}
